// Fill out your copyright notice in the Description page of Project Settings.


#include "Core/Character2D.h"

#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "EnhancedInputSubsystems.h"
#include "EnhancedInputComponent.h"
#include "PaperFlipbookComponent.h"
#include "Core/Bullet.h"
#include "Core/XCZPlayerController.h"




ACharacter2D::ACharacter2D()
{
	SpringArmComponent = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
	CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));

	SpringArmComponent->SetupAttachment(RootComponent);
	CameraComponent->SetupAttachment(SpringArmComponent);

	SpringArmComponent->TargetArmLength = 700;
	SpringArmComponent->bDoCollisionTest = false;
	SpringArmComponent->bEnableCameraLag = true;
	SpringArmComponent->SetRelativeRotation(FRotator(-90.0f, 0.0f, 0.0f));
}

void ACharacter2D::BeginPlay()
{
	Super::BeginPlay();

	// 获取玩家子系统，添加mapping
	AXCZPlayerController* PlayerController = Cast<AXCZPlayerController>(Controller);
	if (PlayerController)
	{
		PlayerController->SetShowMouseCursor(true);
		UEnhancedInputLocalPlayerSubsystem*  InputSystem =  ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer());
		if (InputSystem)
		{
			InputSystem->AddMappingContext(InputMappingContext, 0);
		}
	}

	// 自动开火
	GetWorldTimerManager().SetTimer(AutoFireTimerHandle, this, &ACharacter2D::AutomaticFiring, 0.7f, true);
}

void ACharacter2D::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	UEnhancedInputComponent* EnhancedInputComponent =  Cast<UEnhancedInputComponent>(PlayerInputComponent);
	EnhancedInputComponent->BindAction(IA_Movement, ETriggerEvent::Started, this, &ACharacter2D::StartMovement);
	EnhancedInputComponent->BindAction(IA_Movement, ETriggerEvent::Triggered, this, &ACharacter2D::Movement);
	EnhancedInputComponent->BindAction(IA_Movement, ETriggerEvent::Completed, this, &ACharacter2D::CompletedMovement);
}

void ACharacter2D::StartMovement(const FInputActionValue& Value)
{
	GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green, TEXT("开始移动"));
	bMoving = true;
	MoveState = EMoveState::None;
}

void ACharacter2D::Movement(const FInputActionValue& Value)
{
	GEngine->AddOnScreenDebugMessage(1, 1.0f, FColor::Black, Value.Get<FVector>().ToString());
	FVector ActionValue = Value.Get<FVector>();
	if (!bDead)
	{
		const EMoveState State = ComputeMovementDirection(ActionValue);
		if (State != MoveState)
		{
			MoveState = State;
			UpdateAnimation();
		}
		AddMovementInput(ActionValue);
	}
}

void ACharacter2D::CompletedMovement(const FInputActionValue& Value)
{
	GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green, TEXT("结束移动"));
	bMoving = false;
	UpdateAnimation();
	
}

EMoveState ACharacter2D::ComputeMovementDirection(const FVector& Value)
{
	EMoveState State = Down;
	if (Value.X > 0)
	{
		State = Up;
	}
	else if (Value.X < 0)
	{
		State = Down;
	}
	else if (Value.Y > 0)
	{
		State = Right;
	}
	else if (Value.Y < 0)
	{
		State = Left;
	}
	return State;
}

void ACharacter2D::UpdateAnimation()
{
	UPaperFlipbook* Flipbook = GetAnimation();
	if (Flipbook)
	{
		GetSprite()->SetFlipbook(Flipbook);
	}
}

UPaperFlipbook* ACharacter2D::GetAnimation()
{
	if (bMoving)
	{
		switch (MoveState)
		{
		case Up:
			return *CharacterAnimations.Find("walk_up");
		case Down:
			return *CharacterAnimations.Find("walk_down");
		case Left:
			return *CharacterAnimations.Find("walk_left");
		case Right:
			return *CharacterAnimations.Find("walk_right");
		default:
			return nullptr;
		}
	}
	
	switch (MoveState)
	{
	case Up:
		return *CharacterAnimations.Find("idle_up");
	case Down:
		return *CharacterAnimations.Find("idle_down");
	case Left:
		return *CharacterAnimations.Find("idle_left");
	case Right:
		return *CharacterAnimations.Find("idle_right");
	default:
		return nullptr;
	}
}

UPaperFlipbook* ACharacter2D::GetProperAnim(FString AnimName)
{
	if (CharacterAnimations.Contains(AnimName))
	{
		return CharacterAnimations[AnimName];
	}

	CharacterAnimations.Find(AnimName);
	
	return nullptr;
}

void ACharacter2D::AutomaticFiring()
{
	GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Red, "ACharacter2D::AutomaticFiring()");
	ABullet* Bullet = GetWorld()->SpawnActor<ABullet>(BulletActorToSpawn, GetActorLocation(), FRotator::ZeroRotator);
	
	
}
